import * as XLSX from 'xlsx';

type Filters = (string | ((value: any) => any))[];
type List = Record<string, any>[];

/**
 * @description: 处理json数据以导出excel
 * @param {List} list 要处理的json数据
 * @param {Filters} filter 过滤的值
 * @return {list} json数据转换的二维数组
 * @example
  //使用示例
  const data = [
    { name: '张三', age: 18 },
    { name: '李四', age: 20 }
  ];
  const f = ['name', 'age'];
  const result = excelData(data, f);
  console.log(result); // [['张三',18],['李四',20]]
 */
export function excelData(list: List, filter: Filters): (string | number)[][] {
  return list.map((row) => {
    return filter.map((key) => {
      if (typeof key === 'string') {
        return row[key];
      } else if (typeof key === 'function') {
        return key(row);
      } else {
        throw new Error('The filter of excelData function can only be an array composed of strings or functions');
      }
    });
  });
}

/**
 * @description: 导出excel文件
 * @param {*} params params中包含data，header，fileName，autoWidth四个参数
 * @param {*} params.data data表示excel表格内容数据
 * @param {*} params.header header表示excel表格表头文本
 * @param {*} params.fileName fileName表示导出的文件名
 * @param {*} params.autoWidth autoWidth表示是否设置内容宽度自适应，默认为true
 */
export function exportToExcel({ data, header, fileName, autoWidth = true }) {
  const ws = XLSX.utils.aoa_to_sheet([header, ...data]);

  if (autoWidth) {
    const colWidth = data.map((row) =>
      row.map((val) => {
        if (val == null) {
          return {
            wch: 10
          };
        } else if (val.toString().charCodeAt(0) > 255) {
          return {
            wch: val.toString().length * 2
          };
        } else {
          return {
            wch: val.toString().length
          };
        }
      })
    );
    let result = colWidth[0];
    for (let i = 1; i < colWidth.length; i++) {
      for (let j = 0; j < colWidth[i].length; j++) {
        if (result[j]['wch'] < colWidth[i][j]['wch']) {
          result[j]['wch'] = colWidth[i][j]['wch'];
        }
      }
    }
    ws['!cols'] = result;
  }

  const wb = XLSX.utils.book_new();
  XLSX.utils.book_append_sheet(wb, ws, fileName);
  XLSX.writeFile(wb, fileName + '.xlsx');
}
